<template>
  <div class="chat-page">
    <!-- 左侧对话历史 -->
    <div class="chat-history">
      <div class="history-header">
        <h3>对话历史</h3>
        <el-button type="primary" size="small" @click="createNewChat">
          <el-icon>
            <Plus/>
          </el-icon>
          新对话
        </el-button>
      </div>

      <div class="history-list">
        <div
            v-for="(chat, index) in chatHistory"
            :key="index"
            class="history-item"
            :class="{ active: currentChatIndex === index }"
            @click="switchChat(index)"
        >
          <div class="history-item-title">{{ chat.title || '新对话' }}</div>
          <div class="history-item-time">{{ formatTime(chat.createdAt) }}</div>
          <div class="history-item-actions">
            <el-icon @click.stop="deleteChat(index)">
              <Delete/>
            </el-icon>
          </div>
        </div>
      </div>
    </div>

    <!-- 右侧对话内容 -->
    <div class="chat-content">
      <!-- 连接状态显示和模型选择 -->
      <div class="chat-header">
        <div class="header-left">
          <div class="connection-status" :class="{ connected: isConnected }">
            <el-icon class="status-icon">
              <Connection/>
            </el-icon>
            {{ isConnected ? 'AI 服务已连接' : '正在连接 AI 服务...' }}
            <el-button
                v-if="!isConnected"
                size="small"
                type="primary"
                @click="manualConnect"
                class="connect-btn"
            >
              {{ reconnectFailed ? '重试连接' : '手动连接' }}
            </el-button>
          </div>

          <!-- 添加Token计数显示 -->
          <div class="token-counter" v-if="continuousMode && currentChat && currentChat.messages.length > 0">
            <el-tooltip
                :content="isOverTokenLimit ? '当前Token数量超出限制' : (isNearTokenLimit ? 'Token数量较多' : 'Token数量正常')"
                placement="top">
              <div class="token-badge" :class="{
                'token-normal': !isNearTokenLimit && !isOverTokenLimit,
                'token-warning': isNearTokenLimit && !isOverTokenLimit,
                'token-danger': isOverTokenLimit
              }">
                <span class="token-count-text">{{ estimateCurrentTokenCount }}</span>
                <span class="token-limit-text">/ {{ MAX_TOKEN_LIMIT }}</span>
              </div>
            </el-tooltip>
          </div>
        </div>

        <div class="header-right">
          <div class="model-selector">
            <span class="model-label">模型:</span>
            <el-select
                v-model="selectedModel"
                placeholder="选择模型"
                size="small"
                :disabled="isThinking"
                class="model-select"
            >
              <el-option
                  v-for="item in modelOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
              />
            </el-select>
          </div>

          <div class="chat-mode-switch">
            <span class="mode-label">连续对话:</span>
            <el-switch
                v-model="continuousMode"
                :disabled="isThinking"
                active-color="#67c23a"
                inactive-color="#909399"
                @change="handleModeChange"
            />
            <el-tooltip content="查看对话上下文" placement="top" v-if="continuousMode">
              <el-button
                  type="info"
                  size="small"
                  circle
                  @click="showContextDialog"
                  :disabled="!currentChat || currentChat.messages.length < 2"
                  class="context-btn"
              >
                <el-icon>
                  <InfoFilled/>
                </el-icon>
              </el-button>
            </el-tooltip>
            <el-tooltip content="查看响应时间" placement="top">
              <el-button
                  type="success"
                  size="small"
                  circle
                  @click="showResponseTimeDialog"
                  :disabled="!currentChat || !hasResponseTimes"
                  class="response-time-btn"
              >
                <el-icon>
                  <Timer/>
                </el-icon>
              </el-button>
            </el-tooltip>
          </div>
        </div>
      </div>

      <!-- 聊天记录区域 -->
      <div class="chat-messages" ref="messagesContainer">
        <template v-if="currentChat && currentChat.messages.length > 0">
          <div
              v-for="(message, index) in currentChat.messages"
              :key="index"
              :class="['message', message.role === 'user' ? 'user-message' : (message.role === 'reasoning' ? 'reasoning-message' : 'ai-message')]"
          >
            <div class="message-avatar" v-if="message.role !== 'reasoning'">
              <el-avatar :size="40" :icon="message.role === 'user' ? UserFilled : Service"/>
            </div>
            <div class="message-content">
              <div v-if="message.role === 'user'" class="user-content" @dblclick="fillMessageToInput(message.content)">
                {{ message.content }}
                <div class="message-actions">
                  <el-tooltip content="复制内容" placement="top">
                    <el-button
                        type="text"
                        size="small"
                        @click="copyMessage(message.content)"
                        class="action-icon"
                    >
                      <el-icon>
                        <DocumentCopy/>
                      </el-icon>
                    </el-button>
                  </el-tooltip>
                  <el-tooltip content="填充到输入框" placement="top">
                    <el-button
                        type="text"
                        size="small"
                        @click="fillMessageToInput(message.content)"
                        class="action-icon is-fill"
                    >
                      <el-icon>
                        <EditPen/>
                      </el-icon>
                    </el-button>
                  </el-tooltip>
                  <el-tooltip content="重新发送" placement="top">
                    <el-button
                        type="text"
                        size="small"
                        @click="resendMessage(message.content)"
                        class="action-icon is-resend"
                    >
                      <el-icon class="resend-icon">
                        <RefreshRight/>
                      </el-icon>
                    </el-button>
                  </el-tooltip>
                </div>
              </div>
              <div v-else-if="message.role === 'reasoning'" class="reasoning-content">
                <div class="reasoning-header">
                  <el-icon>
                    <Cpu/>
                  </el-icon>
                  <span>AI 推理过程</span>
                </div>
                <div class="reasoning-text">{{ message.content }}</div>
              </div>
              <div v-else class="ai-content markdown-body" v-html="renderMarkdown(message.content)">
              </div>
              <div v-if="message.role === 'assistant'" class="message-actions">
                <el-tooltip content="复制内容" placement="top">
                  <el-button
                      type="text"
                      size="small"
                      @click="copyMessage(message.content)"
                      class="action-icon"
                  >
                    <el-icon>
                      <DocumentCopy/>
                    </el-icon>
                  </el-button>
                </el-tooltip>
                <el-tooltip content="提取代码" placement="top" v-if="hasCode(message.content)">
                  <el-button
                      type="text"
                      size="small"
                      @click="extractCode(message.content)"
                      class="action-icon"
                  >
                    <el-icon>
                      <Document/>
                    </el-icon>
                  </el-button>
                </el-tooltip>
                <el-tooltip content="查看所有响应时间" placement="top">
                  <el-button
                      type="text"
                      size="small"
                      @click="showResponseTimeDialog"
                      class="action-icon response-time-icon"
                      :disabled="!hasResponseTimes"
                  >
                    <el-icon>
                      <Timer/>
                    </el-icon>
                  </el-button>
                </el-tooltip>
                <div v-if="message.responseTime" class="response-time-indicator">
                  <el-tooltip :content="`响应时间: ${formatResponseTime(message.responseTime)}`" placement="top">
                    <span class="time-badge" :class="getResponseTimeClass(message.responseTime)">
                      <el-icon><Timer/></el-icon>
                      {{ formatResponseTime(message.responseTime) }}
                    </span>
                  </el-tooltip>
                </div>
              </div>
            </div>
          </div>
        </template>
        <div v-else class="empty-chat">
          <el-empty description="开始一个新的对话吧"/>
        </div>
        <div v-if="isThinking" class="message ai-message">
          <div class="message-avatar">
            <el-avatar :size="40" :icon="Service"/>
          </div>
          <div class="message-content thinking-content" :class="{ 'terminating': isTerminating }">
            <el-icon class="thinking-icon">
              <Loading/>
            </el-icon>
            {{ isTerminating ? '正在终止对话...' : '正在思考...' }}
            <el-tooltip content="按 Esc 键快速终止对话" placement="top">
              <el-button
                  v-if="isConnected"
                  type="danger"
                  size="small"
                  @click="terminateConversation"
                  :loading="isTerminating"
                  :disabled="isTerminating"
                  class="terminate-btn"
              >
                <el-icon>
                  <CircleClose/>
                </el-icon>
                {{ isTerminating ? '正在终止...' : '终止对话' }}
              </el-button>
            </el-tooltip>
          </div>
        </div>

        <!-- 未连接状态提示 -->
        <div v-if="!isConnected && !isThinking && (!currentChat || currentChat.messages.length === 0)"
             class="connection-notice">
          <el-icon class="notice-icon">
            <Connection/>
          </el-icon>
          <div class="notice-text">
            <h3>AI 服务未连接</h3>
            <p>请点击下方按钮连接 AI 服务后开始对话</p>
          </div>
          <el-button
              type="primary"
              @click="manualConnect"
              class="notice-connect-btn"
          >
            连接 AI 服务
          </el-button>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="chat-input">
        <el-input
            v-model="userInput"
            type="textarea"
            :rows="3"
            placeholder="请输入您的问题..."
            :disabled="isThinking || !currentChat"
            @keyup.enter.ctrl="handleSend"
        >
          <template #prepend v-if="!isConnected">
            <div class="input-connection-status">
              <el-icon class="status-icon">
                <Connection/>
              </el-icon>
              <span>未连接</span>
              <el-button
                  type="primary"
                  size="small"
                  @click="manualConnect"
                  class="input-connect-btn"
              >
                连接服务
              </el-button>
            </div>
          </template>
        </el-input>
        <div class="input-actions">
          <div class="left-actions">
            <el-tooltip content="清空对话" placement="top">
              <el-button
                  type="danger"
                  plain
                  size="small"
                  @click="clearMessages"
                  :disabled="!currentChat || currentChat.messages.length === 0"
                  class="action-btn"
              >
                <el-icon>
                  <Delete/>
                </el-icon>
                <span>清空</span>
              </el-button>
            </el-tooltip>
            <el-tooltip content="查看响应时间" placement="top">
              <el-button
                  type="success"
                  plain
                  size="small"
                  @click="showResponseTimeDialog"
                  :disabled="!hasResponseTimes"
                  class="action-btn response-time-btn"
              >
                <el-icon>
                  <Timer/>
                </el-icon>
                <span>响应时间</span>
              </el-button>
            </el-tooltip>
          </div>
          <div class="right-actions">
            <span class="hint">Ctrl + Enter 发送</span>
            <template v-if="!isThinking">
              <el-button
                  type="primary"
                  @click="handleSend"
                  :disabled="!userInput.trim() || !currentChat"
                  :class="{ 'not-connected': !isConnected }"
              >
                {{ isConnected ? '发送' : '连接并发送' }}
              </el-button>
            </template>
            <template v-else>
              <el-tooltip content="按 Esc 键快速终止对话" placement="top">
                <el-button
                    type="danger"
                    @click="terminateConversation"
                    :loading="isTerminating"
                    :disabled="!isConnected || isTerminating"
                    class="terminate-input-btn"
                >
                  <el-icon>
                    <CircleClose/>
                  </el-icon>
                  {{ isTerminating ? '正在终止...' : '终止对话' }}
                </el-button>
              </el-tooltip>
            </template>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- 对话上下文对话框 -->
  <el-dialog
      v-model="contextDialogVisible"
      title="对话上下文"
      width="50%"
      destroy-on-close
  >
    <div class="context-dialog-content">
      <div class="context-info">
        <p>当前对话包含 {{ contextMessages.length }} 条消息，估算 Token 数量约 {{ estimateTokenCount }} 个。</p>
      </div>
      <div class="context-messages">
        <div
            v-for="(message, index) in contextMessages"
            :key="index"
            class="context-message"
        >
          <div class="context-message-header">
            <span class="context-role">{{ message.role === 'user' ? '用户' : 'AI' }}</span>
            <span class="context-time">{{ formatTime(message.timestamp) }}</span>
          </div>
          <div class="context-message-content">{{ message.content }}</div>
        </div>
      </div>
    </div>
  </el-dialog>

  <!-- 代码提取对话框 -->
  <el-dialog
      v-model="codeDialogVisible"
      title="提取的代码"
      width="50%"
      append-to-body
      destroy-on-close
      class="code-extract-dialog"
  >
    <div class="code-tabs">
      <el-tabs v-model="activeCodeTab" type="card">
        <el-tab-pane
            v-for="(code, index) in extractedCodes"
            :key="index"
            :label="getCodeLanguage(code) || `代码片段 ${index + 1}`"
            :name="String(index)"
        >
          <div class="code-block-wrapper">
            <div class="code-block-header">
              <span class="code-language">{{ getCodeLanguage(code) || '未知语言' }}</span>
              <div class="code-actions">
                <el-tooltip content="复制代码" placement="top">
                  <el-button
                      type="primary"
                      size="small"
                      @click="copyCode(code)"
                      class="code-action-btn"
                  >
                    <el-icon>
                      <DocumentCopy/>
                    </el-icon>
                    <span>复制</span>
                  </el-button>
                </el-tooltip>
                <el-tooltip content="下载代码" placement="top">
                  <el-button
                      type="success"
                      size="small"
                      @click="downloadCode(code, index)"
                      class="code-action-btn"
                  >
                    <el-icon>
                      <Download/>
                    </el-icon>
                    <span>下载</span>
                  </el-button>
                </el-tooltip>
              </div>
            </div>
            <pre class="code-block hljs"><code v-html="highlightCode(code)"></code></pre>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
  </el-dialog>

  <!-- Token警告对话框 -->
  <el-dialog
      v-model="tokenWarningVisible"
      title="Token数量过多"
      width="500px"
      :close-on-click-modal="false"
      :show-close="false"
      class="token-warning-dialog"
  >
    <div class="token-warning-content">
      <el-alert
          title="当前对话Token数量超出限制"
          type="warning"
          :closable="false"
          show-icon
          class="token-alert"
      >
        <div class="token-info">
          <div class="token-count">
            <span class="token-label">当前Token数量:</span>
            <span class="token-value" :class="{ 'token-over': isOverTokenLimit }">{{ estimateCurrentTokenCount }}</span>
          </div>
          <div class="token-count">
            <span class="token-label">Token限制:</span>
            <span class="token-value">{{ MAX_TOKEN_LIMIT }}</span>
          </div>
          <div class="token-progress">
            <el-progress
                :percentage="Math.min(100, (estimateCurrentTokenCount / MAX_TOKEN_LIMIT) * 100)"
                :status="isOverTokenLimit ? 'exception' : (isNearTokenLimit ? 'warning' : 'success')"
            ></el-progress>
          </div>
        </div>
      </el-alert>

      <div class="token-explanation">
        <p>Token数量过多可能导致以下问题:</p>
        <ul>
          <li>AI无法处理过长的上下文</li>
          <li>回复质量下降</li>
          <li>响应时间变长</li>
        </ul>
        <p>建议采取以下措施:</p>
      </div>

      <div class="token-actions">
        <el-button
            type="primary"
            @click="autoReduceTokens"
            :loading="tokenReduceMode"
            :disabled="!continuousMode.value"
        >
          <el-icon>
            <Delete/>
          </el-icon>
          自动移除早期AI回复
        </el-button>

        <el-button
            type="warning"
            @click="switchToChatMode"
        >
          <el-icon>
            <ChatDotRound/>
          </el-icon>
          切换到单次对话模式
        </el-button>

        <el-button
            type="info"
            @click="tokenWarningVisible = false"
        >
          <el-icon>
            <Edit/>
          </el-icon>
          手动编辑消息
        </el-button>
      </div>

      <div v-if="tokenReduceMode" class="token-reduce-progress">
        <p>正在计算需要移除的消息...</p>
        <el-progress :percentage="tokenReduceProgress"></el-progress>
      </div>
    </div>
  </el-dialog>

  <!-- 响应时间对话框 -->
  <el-dialog
      v-model="responseTimeDialogVisible"
      title="响应时间记录"
      width="50%"
      destroy-on-close
  >
    <div class="response-time-dialog-content">
      <div class="response-time-info">
        <p>当前对话包含 {{ responseTimes.length }} 条响应时间记录。</p>
        <div class="response-time-summary">
          <div class="summary-item">
            <span class="summary-label">平均响应时间:</span>
            <span class="summary-value">{{ formatResponseTime(averageResponseTime) }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">最短响应时间:</span>
            <span class="summary-value">{{ formatResponseTime(minResponseTime) }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">最长响应时间:</span>
            <span class="summary-value">{{ formatResponseTime(maxResponseTime) }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">总响应时间:</span>
            <span class="summary-value">{{ formatResponseTime(totalResponseTime) }}</span>
          </div>
        </div>
      </div>
      <div class="response-time-list">
        <div
            v-for="(item, index) in responseTimes"
            :key="index"
            class="response-time-item"
            :class="{ 'terminated': item.terminated }"
        >
          <div class="response-time-header">
            <span class="response-number">响应 #{{ index + 1 }}</span>
            <span class="response-time">{{ formatTime(item.responseEndTime) }}</span>
          </div>
          <div class="response-time-details">
            <div class="response-time-value">
              <el-icon>
                <Timer/>
              </el-icon>
              <span class="time-value"
                    :class="getResponseTimeClass(item.responseTime)">{{ formatResponseTime(item.responseTime) }}</span>
              <el-tag v-if="item.terminated" size="small" type="danger" class="terminated-tag">已终止</el-tag>
            </div>
            <div class="response-preview">
              <div class="preview-label">用户问题:</div>
              <div class="preview-content user-preview">{{ item.userMessage }}</div>
              <div class="preview-label">AI回复:</div>
              <div class="preview-content ai-preview">{{ truncateText(item.aiMessage, 100) }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import {ref, computed, onMounted, onUnmounted, nextTick, watch} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import {
  Loading,
  Connection,
  Plus,
  Delete,
  UserFilled,
  Service,
  InfoFilled,
  Cpu,
  DocumentCopy,
  Document,
  Download,
  RefreshRight,
  EditPen,
  ChatDotRound,
  Edit,
  CircleClose,
  Timer
} from '@element-plus/icons-vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import 'highlight.js/styles/atom-one-light.css' // 导入一个亮色主题
import config from "@/config"

// 状态
const userInput = ref('')
const isThinking = ref(false)
const isTerminating = ref(false) // 是否正在终止对话
const isConnected = ref(false)
const reconnectFailed = ref(false)
const messagesContainer = ref(null)
let ws = null
let reconnectAttempts = 0
const MAX_RECONNECT_ATTEMPTS = 3

// 响应时间记录
const responseStartTime = ref(0) // 开始响应的时间戳
const responseTimeDialogVisible = ref(false) // 控制响应时间对话框的显示

// 对话历史
const chatHistory = ref([])
const currentChatIndex = ref(null)
const currentChat = computed(() =>
    currentChatIndex.value !== null ? chatHistory.value[currentChatIndex.value] : null
)

// 连续对话模式
const continuousMode = ref(true)

// 对话上下文相关
const contextDialogVisible = ref(false)
const contextMessages = computed(() => {
  if (!currentChat.value) return []

  return currentChat.value.messages
      .filter(msg => msg.role === 'user' || msg.role === 'assistant')
      .sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp))
})

// Token限制相关
const MAX_TOKEN_LIMIT = 8000 // 设置最大token限制
const TOKEN_WARNING_THRESHOLD = 7000 // 设置警告阈值
const tokenWarningVisible = ref(false) // 控制警告对话框的显示
const tokenReduceMode = ref(false) // 是否处于减少token模式
const tokenReduceProgress = ref(0) // token减少进度

// 估算token数量（粗略估计，每4个字符约为1个token）
const estimateTokenCount = computed(() => {
  let totalChars = 0
  contextMessages.value.forEach(msg => {
    totalChars += msg.content.length
  })
  return Math.ceil(totalChars / 4)
})

// 估算当前输入加上历史消息的token数量
const estimateCurrentTokenCount = computed(() => {
  let totalChars = userInput.value.length

  if (continuousMode.value) {
    contextMessages.value.forEach(msg => {
      totalChars += msg.content.length
    })
  }

  return Math.ceil(totalChars / 4)
})

// 检查是否超过token限制
const isOverTokenLimit = computed(() => {
  return estimateCurrentTokenCount.value > MAX_TOKEN_LIMIT
})

// 检查是否接近token限制
const isNearTokenLimit = computed(() => {
  return estimateCurrentTokenCount.value > TOKEN_WARNING_THRESHOLD
})

// 检查当前对话是否有响应时间记录
const hasResponseTimes = computed(() => {
  if (!currentChat.value) return false

  return currentChat.value.messages.some(msg =>
      msg.role === 'assistant' && typeof msg.responseTime === 'number'
  )
})

// 获取响应时间记录
const responseTimes = computed(() => {
  if (!currentChat.value) return []

  const result = []
  const messages = currentChat.value.messages

  for (let i = 0; i < messages.length; i++) {
    const msg = messages[i]
    if (msg.role === 'assistant' && typeof msg.responseTime === 'number') {
      // 找到对应的用户消息
      let userMessage = ''
      for (let j = i - 1; j >= 0; j--) {
        if (messages[j].role === 'user') {
          userMessage = messages[j].content
          break
        }
      }

      result.push({
        responseTime: msg.responseTime,
        responseEndTime: msg.responseEndTime,
        terminated: !!msg.terminated,
        userMessage: userMessage,
        aiMessage: msg.content
      })
    }
  }

  return result
})

// 计算平均响应时间
const averageResponseTime = computed(() => {
  if (responseTimes.value.length === 0) return 0

  const total = responseTimes.value.reduce((sum, item) => sum + item.responseTime, 0)
  return Math.round(total / responseTimes.value.length)
})

// 计算最短响应时间
const minResponseTime = computed(() => {
  if (responseTimes.value.length === 0) return 0

  return Math.min(...responseTimes.value.map(item => item.responseTime))
})

// 计算最长响应时间
const maxResponseTime = computed(() => {
  if (responseTimes.value.length === 0) return 0

  return Math.max(...responseTimes.value.map(item => item.responseTime))
})

// 计算总响应时间
const totalResponseTime = computed(() => {
  if (responseTimes.value.length === 0) return 0

  return responseTimes.value.reduce((sum, item) => sum + item.responseTime, 0)
})

// 截断文本
const truncateText = (text, maxLength) => {
  if (!text) return ''
  if (text.length <= maxLength) return text

  return text.substring(0, maxLength) + '...'
}

// 自动减少token数量
const autoReduceTokens = () => {
  if (!currentChat.value || !continuousMode.value) return

  // 开始减少token模式
  tokenReduceMode.value = true
  tokenReduceProgress.value = 0

  // 获取所有assistant消息
  const assistantMessages = currentChat.value.messages
      .filter(msg => msg.role === 'assistant')
      .sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp)) // 按时间排序，最早的在前

  // 如果没有assistant消息，无法减少
  if (assistantMessages.length === 0) {
    ElMessage.warning('无法减少token数量，请手动缩短您的消息')
    tokenReduceMode.value = false
    return
  }

  // 计算需要移除多少条消息
  let messagesToRemove = []
  let currentTokens = estimateCurrentTokenCount.value
  let index = 0

  while (currentTokens > TOKEN_WARNING_THRESHOLD && index < assistantMessages.length) {
    const msg = assistantMessages[index]
    const msgTokens = Math.ceil(msg.content.length / 4)
    messagesToRemove.push(msg)
    currentTokens -= msgTokens
    index++

    // 更新进度
    tokenReduceProgress.value = Math.min(100, (index / assistantMessages.length) * 100)
  }

  // 如果移除所有assistant消息后仍然超过限制
  if (currentTokens > MAX_TOKEN_LIMIT) {
    ElMessage.warning('即使移除所有AI回复，token数量仍然过多，请手动缩短您的消息')
    tokenReduceMode.value = false
    return
  }

  // 确认移除消息
  ElMessageBox.confirm(
      `将移除${messagesToRemove.length}条较早的AI回复以减少token数量。是否继续？`,
      '确认减少token',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning'
      }
  ).then(() => {
    // 移除消息
    messagesToRemove.forEach(msg => {
      const index = currentChat.value.messages.findIndex(m =>
          m.role === msg.role && m.content === msg.content && m.timestamp === msg.timestamp
      )
      if (index !== -1) {
        currentChat.value.messages.splice(index, 1)
      }
    })

    // 保存更改
    saveChats()

    ElMessage.success(`已移除${messagesToRemove.length}条AI回复，当前token数量约为${estimateCurrentTokenCount.value}`)

    // 结束减少token模式
    tokenReduceMode.value = false
    tokenWarningVisible.value = false
  }).catch(() => {
    // 用户取消
    tokenReduceMode.value = false
    ElMessage.info('已取消减少token操作')
  })
}

// 模型选择
const modelOptions = [
  {value: 'ep-20250204163109-jw9ch', label: 'Doubao-1.5-pro-256k'},
  {value: 'ep-20250204162538-9cmb2', label: 'DeepSeek-R1'},
  {value: 'ep-20250204190620-9n94t', label: 'DeepSeek-V3'},
  {value: 'ep-20250219225638-x9wwt', label: 'DeepSeek-R1-32B'}
]
const selectedModel = ref('ep-20250204190620-9n94t')

// Markdown 渲染器
const md = new MarkdownIt({
  html: true,
  breaks: true,
  linkify: true,
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        const highlighted = hljs.highlight(str, {language: lang, ignoreIllegals: true}).value;
        // 添加复制按钮到代码块
        return `<div class="code-block-wrapper">
                  <div class="code-block-header">
                    <span class="code-language">${lang}</span>
                    <button class="code-copy-btn" title="复制代码" data-code="${encodeURIComponent(str)}">
                      <svg class="copy-icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="14" height="14">
                        <path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32z"></path>
                        <path d="M704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path>
                      </svg>
                    </button>
                  </div>
                  <pre class="hljs"><code class="language-${lang}">${highlighted}</code></pre>
                </div>`;
      } catch (e) {
        console.error('代码高亮错误:', e);
      }
    }
    // 如果没有指定语言或者语言不支持，使用普通的代码块，但仍添加复制按钮
    return `<div class="code-block-wrapper">
              <div class="code-block-header">
                <span class="code-language">代码</span>
                <button class="code-copy-btn" title="复制代码" data-code="${encodeURIComponent(str)}">
                  <svg class="copy-icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="14" height="14">
                    <path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32z"></path>
                    <path d="M704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path>
                  </svg>
                </button>
              </div>
              <pre class="hljs"><code>${md.utils.escapeHtml(str)}</code></pre>
            </div>`;
  }
})

// 渲染 Markdown
const renderMarkdown = (content) => {
  const rendered = md.render(content);
  // 在下一个事件循环中添加事件监听器
  nextTick(() => {
    document.querySelectorAll('.code-copy-btn').forEach(btn => {
      if (!btn.hasListener) {
        btn.addEventListener('click', (e) => {
          const code = decodeURIComponent(e.currentTarget.getAttribute('data-code'));
          copyToClipboard(code);
        });
        btn.hasListener = true;
      }
    });
  });
  return rendered;
}

// 复制到剪贴板的通用函数
const copyToClipboard = (text) => {
  const textarea = document.createElement('textarea');
  textarea.value = text;
  document.body.appendChild(textarea);
  textarea.select();

  try {
    document.execCommand('copy');
    ElMessage.success('代码已复制到剪贴板');
  } catch (err) {
    ElMessage.error('复制失败，请手动复制');
  } finally {
    document.body.removeChild(textarea);
  }
}

// 格式化时间
const formatTime = (timestamp) => {
  const date = new Date(timestamp)
  return `${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`
}

// 格式化响应时间
const formatResponseTime = (ms) => {
  if (!ms) return '未记录'

  if (ms < 1000) {
    return `${ms}毫秒`
  } else if (ms < 60000) {
    return `${(ms / 1000).toFixed(2)}秒`
  } else {
    const minutes = Math.floor(ms / 60000)
    const seconds = ((ms % 60000) / 1000).toFixed(1)
    return `${minutes}分${seconds}秒`
  }
}

// 创建新对话
const createNewChat = () => {
  chatHistory.value.unshift({
    title: '新对话',
    createdAt: new Date().getTime(),
    messages: []
  })
  currentChatIndex.value = 0
  saveChats()
}

// 切换对话
const switchChat = (index) => {
  currentChatIndex.value = index
}

// 删除对话
const deleteChat = (index) => {
  if (chatHistory.value.length === 1) {
    ElMessage.warning('至少保留一个对话')
    return
  }

  chatHistory.value.splice(index, 1)

  if (currentChatIndex.value === index) {
    currentChatIndex.value = 0
  } else if (currentChatIndex.value > index) {
    currentChatIndex.value--
  }

  saveChats()
}

// 清空当前对话消息
const clearMessages = () => {
  if (!currentChat.value) return

  ElMessage.success('对话已清空')
  currentChat.value.messages = []
  saveChats()
}

// 保存对话到本地存储
const saveChats = () => {
  localStorage.setItem('ai-chat-history', JSON.stringify(chatHistory.value))
}

// 从本地存储加载对话
const loadChats = () => {
  const saved = localStorage.getItem('ai-chat-history')
  if (saved) {
    try {
      chatHistory.value = JSON.parse(saved)
      if (chatHistory.value.length > 0) {
        currentChatIndex.value = 0
      }
    } catch (e) {
      console.error('加载对话历史失败:', e)
      chatHistory.value = []
    }
  }

  if (chatHistory.value.length === 0) {
    createNewChat()
  }
}

// 滚动到底部
const scrollToBottom = async () => {
  await nextTick()
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

// 重试连接
const retryConnection = () => {
  reconnectFailed.value = false
  reconnectAttempts = 0
  initWebSocket()
}

// 手动连接
const manualConnect = () => {
  // 显示连接中的状态反馈
  ElMessage({
    message: '正在尝试连接AI服务...',
    type: 'info',
    duration: 2000
  })

  // 重置连接状态
  reconnectFailed.value = false
  reconnectAttempts = 0

  // 如果已有连接，先关闭
  if (ws) {
    try {
      ws.close()
    } catch (e) {
      console.error('关闭现有WebSocket连接失败:', e)
    }
  }

  // 延迟一点时间再连接，让用户看到状态变化
  setTimeout(() => {
    initWebSocket()
  }, 500)
}

// 终止对话
const terminateConversation = () => {
  if (!isThinking.value || !isConnected.value) return

  // 设置终止状态
  isTerminating.value = true

  try {
    // 发送终止信号
    if (ws && ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({
        type: 'terminate'
      }))

      // 显示终止中的状态反馈
      ElMessage({
        message: '正在终止对话...',
        type: 'info',
        duration: 1500
      })

      // 如果服务器没有响应终止请求，我们在一段时间后自行终止
      setTimeout(() => {
        if (isThinking.value) {
          // 强制结束思考状态
          isThinking.value = false
          isTerminating.value = false

          // 如果当前有未完成的AI回复，添加一个终止提示
          if (currentChat.value && currentChat.value.messages.length > 0) {
            const lastMessage = currentChat.value.messages[currentChat.value.messages.length - 1]
            if (lastMessage.role === 'assistant') {
              lastMessage.content += '\n\n[用户已终止回复]'
              saveChats()
            }
          }

          ElMessage.success('对话已终止')
        }
      }, 2000)
    } else {
      // WebSocket未连接，直接结束思考状态
      isThinking.value = false
      isTerminating.value = false
      ElMessage.warning('无法终止对话：AI服务未连接')
    }
  } catch (error) {
    console.error('终止对话错误:', error)
    isThinking.value = false
    isTerminating.value = false
    ElMessage.error('终止对话失败: ' + error.message)
  }
}

// 初始化 WebSocket 连接
const initWebSocket = () => {
  if (ws?.readyState === WebSocket.OPEN) return

  try {
    // 设置连接状态
    isConnected.value = false

    // 创建新的WebSocket连接
    ws = new WebSocket(config.AI_URL)

    ws.onopen = () => {
      console.log('WebSocket连接已建立')
      isConnected.value = true
      reconnectAttempts = 0
      reconnectFailed.value = false

      // 显示连接成功消息
      ElMessage.success('AI 服务连接成功')
    }

    ws.onclose = (event) => {
      console.log('WebSocket连接已关闭', event)
      isConnected.value = false

      // 只有在非手动关闭的情况下才自动重连
      if (!event.wasClean && reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
        reconnectAttempts++
        console.log(`尝试第 ${reconnectAttempts} 次重连...`)
        setTimeout(initWebSocket, 1000 * reconnectAttempts)
      } else {
        reconnectFailed.value = true
        if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
          ElMessage.error('AI 服务连接失败，请手动重试连接')
        }
      }
    }

    ws.onerror = (error) => {
      console.error('WebSocket错误:', error)
      isConnected.value = false

      // 显示错误消息
      if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
        ElMessage.error('AI 服务连接出错，请检查网络后手动重试')
      }
    }

    ws.onmessage = handleMessage
  } catch (error) {
    console.error('创建WebSocket连接错误:', error)
    isConnected.value = false
    reconnectFailed.value = true
    ElMessage.error('创建AI服务连接失败: ' + error.message)
  }
}

// 处理收到的消息
const handleMessage = (event) => {
  try {
    const data = JSON.parse(event.data)
    handleReceive(data);
  } catch (error) {
    console.error('处理消息错误:', error)
    isThinking.value = false
    isTerminating.value = false
    ElMessage.error('处理消息时出错')
  }
}

const handleReceive = (data) => {
  if (data.messageType === 'reasoning') {
    // 处理推理过程
    if (currentChat.value.messages.length > 0 &&
        currentChat.value.messages[currentChat.value.messages.length - 1].role === 'reasoning') {
      // 更新现有的推理消息
      currentChat.value.messages[currentChat.value.messages.length - 1].content += data.content
    } else {
      // 添加新的推理消息
      currentChat.value.messages.push({
        role: 'reasoning',
        content: data.content,
        timestamp: new Date().toISOString()
      })
    }
    scrollToBottom()
  } else if (data.messageType === 'content') {
    if (data.content) {
      // 更新最后一条AI消息，或添加新消息
      if (currentChat.value.messages.length > 0 &&
          currentChat.value.messages[currentChat.value.messages.length - 1].role === 'assistant') {
        currentChat.value.messages[currentChat.value.messages.length - 1].content += data.content
      } else {
        currentChat.value.messages.push({
          role: 'assistant',
          content: data.content,
          timestamp: new Date().toISOString()
        })
      }
      scrollToBottom()
    } else {
      isThinking.value = false
    }
  } else if (data.messageType === 'over') {
    console.log('响应完成')
    // 响应完成
    isThinking.value = false
    isTerminating.value = false

    // 计算响应时间并记录
    if (responseStartTime.value > 0 && currentChat.value) {
      const responseEndTime = Date.now()
      const responseTime = responseEndTime - responseStartTime.value

      // 找到最后一条AI消息，添加响应时间
      const lastMessage = currentChat.value.messages[currentChat.value.messages.length - 1]
      if (lastMessage && lastMessage.role === 'assistant') {
        lastMessage.responseTime = responseTime
        lastMessage.responseEndTime = responseEndTime
        saveChats()
      }

      // 重置开始时间
      responseStartTime.value = 0
    }
  } else if (data.messageType === 'terminated') {
    console.log('terminated')

    // 响应已被终止
    isThinking.value = false
    isTerminating.value = false

    // 计算响应时间并记录（即使是终止的响应）
    if (responseStartTime.value > 0 && currentChat.value) {
      const responseEndTime = Date.now()
      const responseTime = responseEndTime - responseStartTime.value

      // 找到最后一条AI消息，添加响应时间
      const lastMessage = currentChat.value.messages[currentChat.value.messages.length - 1]
      if (lastMessage && lastMessage.role === 'assistant') {
        lastMessage.responseTime = responseTime
        lastMessage.responseEndTime = responseEndTime
        lastMessage.terminated = true
        lastMessage.content += '\n\n[用户已终止回复]'
        saveChats()
      }

      // 重置开始时间
      responseStartTime.value = 0
    } else {
      // 如果当前有未完成的AI回复，添加一个终止提示
      if (currentChat.value && currentChat.value.messages.length > 0) {
        const lastMessage = currentChat.value.messages[currentChat.value.messages.length - 1]
        if (lastMessage.role === 'assistant') {
          lastMessage.content += '\n\n[用户已终止回复]'
          lastMessage.terminated = true
          saveChats()
        }
      }
    }

    ElMessage.success('对话已终止')
  }
}

// 发送消息
const handleSend = () => {
  const message = userInput.value.trim()
  if (!message || isThinking.value || !currentChat.value) return

  // 检查连接状态
  if (!isConnected.value) {
    ElMessageBox.confirm(
        'AI服务未连接，是否尝试连接后发送消息？',
        '连接提示',
        {
          confirmButtonText: '连接并发送',
          cancelButtonText: '取消',
          type: 'warning'
        }
    ).then(() => {
      // 先连接，然后在连接成功后发送消息
      const savedMessage = message

      // 创建一个一次性的连接成功监听器
      const checkAndSend = () => {
        if (isConnected.value) {
          // 连接成功后，重新设置输入并调用发送
          userInput.value = savedMessage
          // 使用setTimeout确保状态更新后再次调用
          setTimeout(() => {
            handleSendMessage(savedMessage)
          }, 100)
          // 移除监听器
          clearInterval(intervalId)
        }
      }

      // 设置一个间隔检查连接状态
      const intervalId = setInterval(checkAndSend, 500)

      // 10秒后如果还没连接成功，就清除定时器
      setTimeout(() => {
        if (intervalId) {
          clearInterval(intervalId)
          if (!isConnected.value) {
            ElMessage.error('连接超时，请手动重试')
          }
        }
      }, 10000)

      // 尝试连接
      manualConnect()
    }).catch(() => {
      // 用户取消
      ElMessage.info('已取消发送')
    })
    return
  }

  // 检查token数量
  if (continuousMode.value && isOverTokenLimit.value) {
    tokenWarningVisible.value = true
    return
  }

  // 如果接近token限制，显示警告但允许发送
  if (continuousMode.value && isNearTokenLimit.value) {
    ElMessage({
      message: `当前token数量较多(约${estimateCurrentTokenCount.value})，可能影响AI回复质量`,
      type: 'warning',
      duration: 3000
    })
  }

  // 执行实际的发送逻辑
  handleSendMessage(message)
}

// 实际处理发送消息的逻辑
const handleSendMessage = (message) => {
  // 添加用户消息
  currentChat.value.messages.push({
    role: 'user',
    content: message,
    timestamp: new Date().toISOString()
  })
  userInput.value = ''
  scrollToBottom()

  // 如果是第一条消息，立即更新对话标题
  if (currentChat.value.messages.length === 1 && (!currentChat.value.title || currentChat.value.title === '新对话')) {
    // 使用用户的第一条消息作为标题（截取前20个字符）
    currentChat.value.title = message.length > 20
        ? message.substring(0, 20) + '...'
        : message
  }

  saveChats()

  // 设置思考状态
  isThinking.value = true
  isTerminating.value = false

  // 记录开始响应的时间
  responseStartTime.value = Date.now()

  // 准备消息历史（如果是连续对话模式）
  let ms = [];

  if (continuousMode.value) {
    // 连续对话模式：包含历史消息
    ms = currentChat.value.messages
        .filter(msg => msg.role === 'user' || msg.role === 'assistant')
        .map(msg => ({
          role: msg.role,
          content: msg.content
        }))
  } else {
    // 非连续对话模式：只包含当前消息
    ms = [{
      role: 'user',
      content: message
    }]
  }

  // 发送到WebSocket
  try {
    ws.send(JSON.stringify({
      type: 'batchV3',
      message: JSON.stringify(ms),
      model: selectedModel.value,
      stream: true
    }))
  } catch (error) {
    console.error('发送消息错误:', error)
    isThinking.value = false

    // 显示更详细的错误信息
    if (!isConnected.value) {
      ElMessage.error('发送失败：AI服务未连接，请重新连接后再试')
    } else {
      ElMessage.error(`发送失败：${error.message || '未知错误'}`)
    }

    // 如果是连接问题，提示用户重新连接
    if (error.message && (error.message.includes('CLOSED') || error.message.includes('close'))) {
      setTimeout(() => {
        ElMessageBox.confirm(
            'AI服务连接已断开，是否尝试重新连接？',
            '连接断开',
            {
              confirmButtonText: '重新连接',
              cancelButtonText: '取消',
              type: 'warning'
            }
        ).then(() => {
          manualConnect()
        }).catch(() => {
        })
      }, 100)
    }
  }
}

// 显示对话上下文
const showContextDialog = () => {
  if (!currentChat.value || currentChat.value.messages.length < 2) {
    ElMessage.warning('对话历史不足，无法显示上下文')
    return
  }
  contextDialogVisible.value = true
}

// 代码提取相关
const codeDialogVisible = ref(false)
const extractedCodes = ref([])
const activeCodeTab = ref('0')

// 复制消息
const copyMessage = (content) => {
  // 创建一个临时textarea元素
  const textarea = document.createElement('textarea')
  textarea.value = content
  document.body.appendChild(textarea)
  textarea.select()

  try {
    // 执行复制命令
    document.execCommand('copy')
    ElMessage.success('已复制到剪贴板')
  } catch (err) {
    ElMessage.error('复制失败，请手动复制')
  } finally {
    document.body.removeChild(textarea)
  }
}

// 检查消息是否包含代码块
const hasCode = (content) => {
  return content.includes('```')
}

// 提取代码块
const extractCode = (content) => {
  const codeBlockRegex = /```(\w*)\n([\s\S]*?)```/g
  let match
  const codes = []

  while ((match = codeBlockRegex.exec(content)) !== null) {
    codes.push({
      language: match[1].trim(),
      content: match[2].trim()
    })
  }

  if (codes.length > 0) {
    extractedCodes.value = codes
    activeCodeTab.value = '0'
    codeDialogVisible.value = true
  } else {
    ElMessage.warning('未找到代码块')
  }
}

// 获取代码语言名称
const getCodeLanguage = (code) => {
  if (!code.language) return null

  const languageMap = {
    'javascript': 'JavaScript',
    'js': 'JavaScript',
    'typescript': 'TypeScript',
    'ts': 'TypeScript',
    'html': 'HTML',
    'css': 'CSS',
    'java': 'Java',
    'python': 'Python',
    'py': 'Python',
    'c': 'C',
    'cpp': 'C++',
    'csharp': 'C#',
    'cs': 'C#',
    'php': 'PHP',
    'go': 'Go',
    'rust': 'Rust',
    'ruby': 'Ruby',
    'swift': 'Swift',
    'kotlin': 'Kotlin',
    'sql': 'SQL',
    'shell': 'Shell',
    'bash': 'Bash',
    'json': 'JSON',
    'xml': 'XML',
    'yaml': 'YAML',
    'yml': 'YAML',
    'markdown': 'Markdown',
    'md': 'Markdown',
    'vue': 'Vue'
  }

  return languageMap[code.language.toLowerCase()] || code.language
}

// 高亮显示代码
const highlightCode = (code) => {
  if (code.language && hljs.getLanguage(code.language)) {
    try {
      return hljs.highlight(code.content, {language: code.language, ignoreIllegals: true}).value
    } catch (e) {
      console.error('代码高亮错误:', e)
    }
  }
  return hljs.highlightAuto(code.content).value
}

// 复制代码
const copyCode = (code) => {
  const textarea = document.createElement('textarea')
  textarea.value = code.content
  document.body.appendChild(textarea)
  textarea.select()

  try {
    document.execCommand('copy')
    ElMessage.success('代码已复制到剪贴板')
  } catch (err) {
    ElMessage.error('复制失败，请手动复制')
  } finally {
    document.body.removeChild(textarea)
  }
}

// 下载代码
const downloadCode = (code, index) => {
  // 确定文件扩展名
  let extension = '.txt'
  if (code.language) {
    const extensionMap = {
      'javascript': '.js',
      'js': '.js',
      'typescript': '.ts',
      'ts': '.ts',
      'html': '.html',
      'css': '.css',
      'java': '.java',
      'python': '.py',
      'py': '.py',
      'c': '.c',
      'cpp': '.cpp',
      'csharp': '.cs',
      'cs': '.cs',
      'php': '.php',
      'go': '.go',
      'rust': '.rs',
      'ruby': '.rb',
      'swift': '.swift',
      'kotlin': '.kt',
      'sql': '.sql',
      'shell': '.sh',
      'bash': '.sh',
      'json': '.json',
      'xml': '.xml',
      'yaml': '.yml',
      'yml': '.yml',
      'markdown': '.md',
      'md': '.md',
      'vue': '.vue'
    }
    extension = extensionMap[code.language.toLowerCase()] || '.txt'
  }

  // 创建下载链接
  const blob = new Blob([code.content], {type: 'text/plain'})
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `code_snippet_${index + 1}${extension}`
  document.body.appendChild(a)
  a.click()

  // 清理
  setTimeout(() => {
    document.body.removeChild(a)
    URL.revokeObjectURL(url)
  }, 100)

  ElMessage.success('代码已下载')
}

// 重发消息
const resendMessage = (content) => {
  if (isThinking.value || !isConnected.value) {
    ElMessage.warning('请等待当前响应完成或确保AI服务已连接')
    return
  }

  // 添加旋转动画
  const resendIcons = document.querySelectorAll('.resend-icon')
  resendIcons.forEach(icon => {
    icon.classList.add('resend-animation')
    setTimeout(() => {
      icon.classList.remove('resend-animation')
    }, 800)
  })

  // 清除之前的思考状态
  isThinking.value = false

  // 设置输入框内容
  userInput.value = content

  // 添加视觉反馈
  ElMessage({
    message: '正在重新发送消息...',
    type: 'info',
    duration: 1500
  })

  // 滚动到底部并聚焦输入框
  nextTick(() => {
    scrollToBottom()

    // 短暂延迟后发送消息，让用户有时间看到反馈
    setTimeout(() => {
      handleSend()
    }, 300)
  })
}

// 填充消息到输入框
const fillMessageToInput = (content) => {
  userInput.value = content

  // 聚焦输入框
  nextTick(() => {
    const textarea = document.querySelector('.el-textarea__inner')
    if (textarea) {
      textarea.focus()
    }
  })

  ElMessage({
    message: '消息已填充到输入框',
    type: 'success',
    duration: 1500
  })
}

// 切换到单次对话模式
const switchToChatMode = () => {
  continuousMode.value = false
  tokenWarningVisible.value = false
  ElMessage.success('已切换到单次对话模式，不再使用历史消息')
}

// 生命周期钩子
onMounted(() => {
  loadChats()
  initWebSocket()

  // 添加页面可见性变化监听，在页面重新可见时尝试重新连接
  document.addEventListener('visibilitychange', handleVisibilityChange)

  // 添加键盘事件监听，用于终止对话
  document.addEventListener('keydown', handleKeyDown)
})

onUnmounted(() => {
  // 清理WebSocket连接
  if (ws) {
    try {
      ws.close()
    } catch (e) {
      console.error('关闭WebSocket连接失败:', e)
    }
    ws = null
  }

  // 移除页面可见性监听
  document.removeEventListener('visibilitychange', handleVisibilityChange)

  // 移除键盘事件监听
  document.removeEventListener('keydown', handleKeyDown)
})

// 处理页面可见性变化
const handleVisibilityChange = () => {
  if (document.visibilityState === 'visible') {
    // 页面变为可见时，如果连接已断开，尝试重新连接
    if (!isConnected.value && ws?.readyState !== WebSocket.OPEN && ws?.readyState !== WebSocket.CONNECTING) {
      console.log('页面重新可见，尝试重新连接WebSocket')
      manualConnect()
    }
  }
}

// 处理键盘事件
const handleKeyDown = (event) => {
  // 按下 Escape 键终止对话
  if (event.key === 'Escape' && isThinking.value && isConnected.value && !isTerminating.value) {
    terminateConversation()
  }
}

// 监听消息变化，保存对话
watch(() => {
  if (currentChat.value) {
    return [...currentChat.value.messages]
  }
  return []
}, () => {
  saveChats()
}, {deep: true})

// 显示响应时间对话框
const showResponseTimeDialog = () => {
  if (!currentChat.value) {
    ElMessage.warning('没有当前对话')
    return
  }

  if (!hasResponseTimes.value) {
    ElMessage.warning('当前对话没有响应时间记录')
    return
  }

  responseTimeDialogVisible.value = true
}

// 获取响应时间类
const getResponseTimeClass = (responseTime) => {
  if (responseTime < 1000) return 'fast'
  if (responseTime < 60000) return 'medium'
  return 'slow'
}
</script>

<style scoped>
.chat-page {
  display: flex;
  height: calc(100vh - 120px);
  background-color: #f9fafc;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  animation: fadeIn 0.5s ease-in-out;
}

.chat-history {
  width: 280px;
  background-color: #fff;
  border-right: 1px solid #ebeef5;
  display: flex;
  flex-direction: column;
}

.history-header {
  padding: 16px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #f9fafc;
}

.history-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

/* 新对话按钮样式 */
.history-header .el-button {
  background-color: #ecf5ff;
  border-color: #d9ecff;
  color: #409eff;
  transition: all 0.3s;
}

.history-header .el-button:hover {
  background-color: #409eff;
  border-color: #409eff;
  color: #fff;
  transform: translateY(-1px);
}

.history-item-actions .el-icon {
  color: #c0c4cc;
  transition: all 0.3s;
  padding: 4px;
  border-radius: 4px;
}

.history-item-actions .el-icon:hover {
  color: #f56c6c;
  background-color: #fef0f0;
  transform: scale(1.1);
}

.history-list {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
}

.history-item {
  padding: 12px;
  border-radius: 8px;
  margin-bottom: 10px;
  cursor: pointer;
  position: relative;
  transition: all 0.3s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
}

.history-item:hover {
  background-color: #f5f7fa;
  transform: translateY(-1px);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
}

.history-item.active {
  background-color: #ecf5ff;
  border-left: 3px solid #409eff;
}

.history-item-title {
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.history-item-time {
  font-size: 12px;
  color: #909399;
}

.history-item-actions {
  position: absolute;
  right: 12px;
  top: 12px;
  opacity: 0;
  transition: opacity 0.3s;
}

.history-item:hover .history-item-actions {
  opacity: 1;
}

.chat-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 20px;
  background-color: #fff;
}

/* 聊天头部 */
.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  flex-wrap: wrap;
  gap: 12px;
  padding-bottom: 16px;
  border-bottom: 1px solid #ebeef5;
}

.header-left {
  display: flex;
  align-items: center;
  flex: 1;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

.connection-status {
  padding: 8px 12px;
  background-color: #fff3e6;
  color: #e6a23c;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  transition: all 0.3s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.connection-status.connected {
  background-color: #f0f9eb;
  color: #67c23a;
}

.status-icon {
  animation: pulse 2s infinite;
}

.connected .status-icon {
  animation: none;
}

.connect-btn {
  margin-left: auto;
  transition: all 0.3s;
  background-color: #ecf5ff;
  border-color: #d9ecff;
  color: #409eff;
}

.connect-btn:hover {
  background-color: #409eff;
  border-color: #409eff;
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

.model-selector {
  display: flex;
  align-items: center;
  gap: 8px;
}

.model-label {
  font-size: 14px;
  color: #606266;
}

.model-select {
  width: 180px;
  transition: all 0.3s;
}

.model-select:hover {
  box-shadow: 0 0 8px rgba(64, 158, 255, 0.2);
}

.chat-mode-switch {
  display: flex;
  align-items: center;
  gap: 8px;
}

.mode-label {
  font-size: 14px;
  color: #606266;
}

.context-btn {
  margin-left: 8px;
  transition: all 0.3s;
}

.context-btn:hover {
  transform: scale(1.05);
  background-color: #ecf5ff;
  color: #409eff;
}

.reasoning-mode-switch {
  display: none; /* 隐藏推理模式开关 */
}

@keyframes pulse {
  0% {
    opacity: 0.6;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0.6;
  }
}

/* Token计数器样式保持优化 */
.token-counter {
  display: flex;
  align-items: center;
  margin-left: 15px;
}

.token-badge {
  display: flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.token-normal {
  background-color: #f0f9eb;
  color: #67c23a;
}

.token-warning {
  background-color: #fdf6ec;
  color: #e6a23c;
}

.token-danger {
  background-color: #fef0f0;
  color: #f56c6c;
}

.token-count-text {
  font-weight: 600;
}

.token-limit-text {
  opacity: 0.7;
  margin-left: 2px;
}

.token-badge:hover {
  transform: scale(1.05);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  background-color: #f9fafc;
  border-radius: 12px;
  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.03);
  margin-bottom: 20px;
}

.chat-messages::-webkit-scrollbar {
  width: 6px;
}

.chat-messages::-webkit-scrollbar-thumb {
  background-color: #c0c4cc;
  border-radius: 3px;
  transition: all 0.3s;
}

.chat-messages::-webkit-scrollbar-thumb:hover {
  background-color: #909399;
}

.chat-messages::-webkit-scrollbar-track {
  background-color: transparent;
}

.empty-chat {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #909399;
}

:deep(.empty-chat .el-empty__image) {
  width: 120px;
  height: 120px;
}

:deep(.empty-chat .el-empty__description) {
  margin-top: 16px;
  font-size: 16px;
  color: #909399;
}

.message {
  display: flex;
  margin-bottom: 16px;
  animation: fadeIn 0.3s ease-in-out;
}

.message-avatar {
  margin-right: 12px;
  flex-shrink: 0;
}

.message-content {
  flex: 1;
  max-width: calc(100% - 60px);
  transition: all 0.3s ease;
}

.user-message {
  flex-direction: row;
}

.ai-message {
  flex-direction: row;
}

.user-content {
  background-color: #ecf5ff;
  color: #303133;
  padding: 12px 16px;
  border-radius: 12px 12px 0 12px;
  font-size: 14px;
  line-height: 1.4;
  white-space: pre-wrap;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  border: 1px solid rgba(64, 158, 255, 0.1);
  cursor: pointer;
  transition: all 0.2s ease;
}

.user-content:hover {
  background-color: #e0f0ff;
  border-color: rgba(64, 158, 255, 0.3);
}

.ai-content {
  background-color: #ffffff;
  color: #303133;
  padding: 12px 16px;
  border-radius: 12px 12px 12px 0;
  font-size: 14px;
  line-height: 1.4;
  white-space: pre-wrap;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  border: 1px solid #ebeef5;
}

.thinking-content {
  background-color: #f4f4f5;
  color: #909399;
  font-style: italic;
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  position: relative;
}

.thinking-icon {
  margin-right: 8px;
  animation: rotate 1s linear infinite;
}

.terminate-btn {
  margin-left: auto;
  background-color: #fef0f0;
  border-color: #fde2e2;
  color: #f56c6c;
  transition: all 0.3s;
  display: flex;
  align-items: center;
  gap: 4px;
}

.terminate-btn:hover {
  background-color: #f56c6c;
  border-color: #f56c6c;
  color: #fff;
  transform: translateY(-1px);
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.chat-input {
  background-color: #fff;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #ebeef5;
}

.input-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 16px; /* 增加上边距 */
}

.left-actions, .right-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 4px;
}

.left-actions .action-btn {
  background-color: #fef0f0;
  border-color: #fde2e2;
  color: #f56c6c;
  transition: all 0.3s;
}

.left-actions .action-btn:hover {
  background-color: #f56c6c;
  border-color: #f56c6c;
  color: #fff;
  transform: translateY(-1px);
}

.left-actions .action-btn.response-time-btn {
  background-color: #f0f9eb;
  border-color: #e1f3d8;
  color: #67c23a;
}

.left-actions .action-btn.response-time-btn:hover {
  background-color: #67c23a;
  border-color: #67c23a;
  color: #fff;
  transform: translateY(-1px);
}

.right-actions .el-button {
  background-color: #409eff;
  border-color: #409eff;
  color: #fff;
  transition: all 0.3s;
  padding: 10px 20px; /* 增加内边距 */
  font-weight: 500; /* 增加字重 */
}

.right-actions .el-button:hover {
  background-color: #66b1ff;
  border-color: #66b1ff;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

.right-actions .el-button.not-connected {
  background-color: #e6a23c;
  border-color: #e6a23c;
  color: #fff;
}

.right-actions .el-button.not-connected:hover {
  background-color: #ebb563;
  border-color: #ebb563;
  box-shadow: 0 2px 8px rgba(230, 162, 60, 0.3);
}

.hint {
  font-size: 12px;
  color: #909399;
  margin-right: 12px; /* 增加右边距 */
}

/* 对话上下文对话框 */
.context-dialog-content {
  max-height: 60vh;
  overflow-y: auto;
  padding: 4px; /* 添加内边距 */
}

.context-info {
  margin-bottom: 16px;
  padding: 14px; /* 增加内边距 */
  background-color: #f0f9eb; /* 更改背景色 */
  border-radius: 8px; /* 增加圆角 */
  font-size: 14px;
  color: #67c23a; /* 更改文字颜色 */
  border-left: 3px solid #67c23a; /* 添加左边框 */
}

.context-messages {
  display: flex;
  flex-direction: column;
  gap: 14px; /* 增加间距 */
}

.context-message {
  padding: 14px; /* 增加内边距 */
  border-radius: 8px; /* 增加圆角 */
  background-color: #f9fafc; /* 更改背景色 */
  border-left: 3px solid #dcdfe6;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05); /* 添加阴影 */
}

.context-message-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 13px;
}

.context-role {
  font-weight: 600;
  color: #409eff;
}

.context-time {
  color: #909399;
}

.context-message-content {
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  color: #303133;
}

/* Markdown 样式 */
:deep(.markdown-body) {
  font-size: 14px;
  line-height: 1.4;
  color: #303133;
}

:deep(.markdown-body h3,ul,li) {
  margin: 0;
  padding: 0;
}

:deep(.markdown-body h3::after) {
  margin: 0;
  padding: 0;
}

:deep(.markdown-body code) {
  font-family: Consolas, Monaco, 'Andale Mono', monospace;
  font-size: 13px;
  line-height: 1.4;
}

:deep(.markdown-body .code-block-wrapper) {
  overflow: hidden;
  padding: 0;
}


:deep(.markdown-body .code-block-header) {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2px 10px; /* 调整内边距 */
  background-color: #f8f9fa;
  border-bottom: 1px solid #eaecef;
  height: 22px;
}

:deep(.markdown-body .code-language) {
  font-size: 11px;
  color: #606266; /* 调整颜色 */
  font-weight: 500;
  text-transform: capitalize;
}

:deep(.markdown-body .code-copy-btn) {
  background-color: transparent;
  border: none;
  border-radius: 4px; /* 调整圆角 */
  padding: 3px;
  font-size: 11px;
  color: #909399;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  height: 20px;
  width: 20px;
}

:deep(.markdown-body .code-copy-btn:hover) {
  background-color: #ecf5ff; /* 调整悬停背景色 */
  color: #409eff; /* 调整悬停文字颜色 */
}

:deep(.markdown-body .code-copy-btn .copy-icon) {
  fill: currentColor;
}

:deep(.markdown-body pre) {
  background-color: #f8f9fa;
  border-radius: 0;
  padding: 12px 14px; /* 调整内边距 */
  overflow-x: auto;
  margin: 0;
}

:deep(.markdown-body code) {
  font-family: 'JetBrains Mono', Consolas, Monaco, 'Andale Mono', monospace; /* 使用更好的代码字体 */
  font-size: 13px;
  line-height: 1.5; /* 调整行高 */
}

:deep(.markdown-body p) {
  margin: 4px 0;
  line-height: 1.5;
}

:deep(.markdown-body ul, .markdown-body ol) {
  padding-left: 20px;
  margin: 4px 0;
}

:deep(.markdown-body li) {
  margin-bottom: 1px;
  line-height: 1.4;
}

:deep(.markdown-body h1, .markdown-body h2, .markdown-body h3,
       .markdown-body h4, .markdown-body h5, .markdown-body h6) {
  margin-top: 8px;
  margin-bottom: 8px;
  line-height: 1.3;
}

:deep(.markdown-body blockquote) {
  margin: 4px 0;
  padding: 4px 12px;
  border-left: 4px solid #dcdfe6;
  background-color: #f9fafc;
  color: #606266;
}

:deep(.markdown-body table) {
  border-collapse: collapse;
  width: 100%;
  margin: 8px 0;
}

:deep(.markdown-body th, .markdown-body td) {
  border: 1px solid #dcdfe6;
  padding: 8px 12px;
}

:deep(.markdown-body th) {
  background-color: #f5f7fa;
}

/* 代码高亮样式 */
:deep(.hljs) {
  background-color: #f8f9fa;
  border-radius: 0;
  padding: 0;
  margin: 0;
  font-family: 'JetBrains Mono', Consolas, Monaco, 'Andale Mono', monospace; /* 使用更好的代码字体 */
}

:deep(.hljs .hljs-keyword),
:deep(.hljs .hljs-selector-tag),
:deep(.hljs .hljs-title),
:deep(.hljs .hljs-section) {
  color: #d73a49;
  font-weight: bold;
}

:deep(.hljs .hljs-string),
:deep(.hljs .hljs-doctag) {
  color: #032f62;
}

:deep(.hljs .hljs-title.function_) {
  color: #6f42c1;
}

:deep(.hljs .hljs-number),
:deep(.hljs .hljs-literal) {
  color: #005cc5;
}

:deep(.hljs .hljs-comment) {
  color: #6a737d;
  font-style: italic;
}

:deep(.hljs .hljs-attr),
:deep(.hljs .hljs-attribute) {
  color: #005cc5;
}

:deep(.hljs .hljs-variable),
:deep(.hljs .hljs-template-variable) {
  color: #e36209;
}

:deep(.hljs .hljs-tag) {
  color: #22863a;
}

:deep(.hljs .hljs-name) {
  color: #22863a;
  font-weight: bold;
}

:deep(.hljs .hljs-regexp) {
  color: #032f62;
}

:deep(.hljs .hljs-meta) {
  color: #6a737d;
}

:deep(.hljs .hljs-built_in) {
  color: #6f42c1;
}

.reasoning-message {
  margin-bottom: 8px;
  padding-left: 52px;
}

.reasoning-content {
  background-color: #f8f9fa;
  border-radius: 10px;
  border-left: 3px solid #909399;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  margin-bottom: 4px;
}

.reasoning-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background-color: #f4f4f5;
  color: #606266;
  font-size: 13px;
  font-weight: 500;
  border-bottom: 1px solid #ebeef5;
}

.reasoning-text {
  padding: 12px 16px;
  font-size: 14px;
  line-height: 1.4;
  white-space: pre-wrap;
  color: #606266;
  font-style: italic;
}

.message-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
  opacity: 0;
  transition: opacity 0.3s;
}

.message:hover .message-actions {
  opacity: 1;
}

.action-icon {
  color: #909399;
  padding: 6px;
  border-radius: 6px;
  transition: all 0.2s;
}

.action-icon:hover {
  color: #409eff;
  background-color: #ecf5ff;
  transform: scale(1.05);
}

/* 代码提取对话框样式 */
.code-tabs {
  height: 100%;
}

.code-block-wrapper {
  border: 1px solid #eaecef;
  border-radius: 8px; /* 增加圆角 */
  overflow: hidden;
  margin-top: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); /* 添加阴影 */
}

.code-block-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 16px; /* 增加内边距 */
  background-color: #f8f9fa;
  border-bottom: 1px solid #eaecef;
}

.code-language {
  font-size: 14px;
  font-weight: 500;
  color: #409eff; /* 更改颜色 */
}

.code-actions {
  display: flex;
  gap: 10px; /* 增加间距 */
}

.code-action-btn {
  display: flex;
  align-items: center;
  gap: 6px; /* 增加间距 */
  transition: all 0.3s; /* 添加过渡效果 */
}

.code-action-btn:hover {
  transform: translateY(-1px); /* 添加悬停效果 */
}

.code-block {
  margin: 0;
  padding: 16px;
  max-height: 400px;
  overflow: auto;
  background-color: #f8f9fa;
  font-family: Consolas, Monaco, 'Andale Mono', monospace;
  font-size: 13px;
  line-height: 1.5;
}

:deep(.el-tabs__item) {
  height: 36px; /* 增加高度 */
  line-height: 36px; /* 增加行高 */
  font-size: 14px; /* 增加字体大小 */
  transition: all 0.3s; /* 添加过渡效果 */
}

:deep(.el-tabs__item.is-active) {
  color: #409eff;
  font-weight: 500; /* 增加字重 */
}

:deep(.el-tabs__active-bar) {
  background-color: #409eff;
  height: 3px; /* 增加高度 */
}

:deep(.el-dialog__body) {
  padding: 20px 24px; /* 增加内边距 */
}

:deep(.el-dialog__header) {
  padding: 16px 24px; /* 增加内边距 */
  border-bottom: 1px solid #ebeef5; /* 添加下边框 */
  margin-right: 0; /* 重置右边距 */
}

:deep(.el-dialog__title) {
  font-size: 18px; /* 增加字体大小 */
  font-weight: 600; /* 增加字重 */
  color: #303133; /* 添加颜色 */
}

:deep(.el-dialog__headerbtn) {
  top: 16px; /* 调整位置 */
  right: 16px; /* 调整位置 */
}

:deep(.el-dialog__footer) {
  padding: 16px 24px; /* 增加内边距 */
  border-top: 1px solid #ebeef5; /* 添加上边框 */
}

/* 添加一些全局动画效果 */
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 美化滚动条 */
.chat-messages::-webkit-scrollbar {
  width: 6px;
}

.chat-messages::-webkit-scrollbar-thumb {
  background-color: #c0c4cc;
  border-radius: 3px;
  transition: all 0.3s;
}

.chat-messages::-webkit-scrollbar-thumb:hover {
  background-color: #909399;
}

.chat-messages::-webkit-scrollbar-track {
  background-color: transparent;
}

/* 美化输入框 */
:deep(.el-textarea__inner) {
  border-radius: 8px;
  border-color: #dcdfe6;
  transition: all 0.3s;
  padding: 12px;
  font-size: 14px;
  line-height: 1.5;
  resize: none;
}

:deep(.el-textarea__inner:focus) {
  border-color: #409eff;
  box-shadow: 0 0 8px rgba(64, 158, 255, 0.2);
}

:deep(.el-textarea__inner:hover) {
  border-color: #c0c4cc;
}

/* 美化头像 */
:deep(.el-avatar) {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 2px solid #fff;
  transition: all 0.3s;
}

:deep(.user-message .el-avatar) {
  background-color: #ecf5ff;
  color: #409eff;
}

:deep(.ai-message .el-avatar) {
  background-color: #f0f9eb;
  color: #67c23a;
}

/* 美化对话框 */
:deep(.el-dialog) {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

/* 美化按钮 */
:deep(.el-button) {
  border-radius: 8px;
  transition: all 0.3s;
}

:deep(.el-button:hover) {
  transform: translateY(-1px);
}

:deep(.el-button--primary) {
  background-color: #409eff;
  border-color: #409eff;
}

:deep(.el-button--primary:hover) {
  background-color: #66b1ff;
  border-color: #66b1ff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

:deep(.el-button--danger) {
  background-color: #f56c6c;
  border-color: #f56c6c;
}

:deep(.el-button--danger:hover) {
  background-color: #f78989;
  border-color: #f78989;
  box-shadow: 0 2px 8px rgba(245, 108, 108, 0.3);
}

/* 美化选择器 */
:deep(.el-select .el-input__inner) {
  border-radius: 8px;
}

:deep(.el-select-dropdown) {
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

:deep(.el-select-dropdown__item.selected) {
  color: #409eff;
  font-weight: 500;
}

:deep(.el-select-dropdown__item:hover) {
  background-color: #ecf5ff;
}

/* 添加响应式调整 */
@media (max-width: 768px) {
  .chat-page {
    flex-direction: column;
  }

  .chat-history {
    width: 100%;
    height: 200px;
    overflow-y: auto;
  }

  .chat-content {
    padding: 16px;
  }

  .chat-header {
    flex-direction: column;
    align-items: flex-start;
  }

  .connection-status {
    width: 100%;
  }
}

/* 添加重发按钮的样式 */
.action-icon.is-resend {
  color: #e6a23c;
}

.action-icon.is-resend:hover {
  color: #f56c6c;
  background-color: #fef0f0;
}

.resend-icon {
  transition: transform 0.3s ease;
}

.action-icon.is-resend:hover .resend-icon {
  transform: rotate(180deg);
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.resend-animation {
  animation: spin 0.8s linear;
}

/* 添加填充按钮的样式 */
.action-icon.is-fill {
  color: #409eff;
}

.action-icon.is-fill:hover {
  color: #66b1ff;
  background-color: #ecf5ff;
}

.action-icon.response-time-icon {
  color: #67c23a;
}

.action-icon.response-time-icon:hover {
  color: #85ce61;
  background-color: #f0f9eb;
}

/* Token警告对话框样式 */
.token-warning-content {
  padding: 10px;
}

.token-alert {
  margin-bottom: 20px;
}

.token-info {
  margin-top: 10px;
  padding: 10px;
  background-color: #f9fafc;
  border-radius: 8px;
}

.token-count {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 14px;
}

.token-label {
  font-weight: 500;
  color: #606266;
}

.token-value {
  font-weight: 600;
  color: #67c23a;
}

.token-value.token-over {
  color: #f56c6c;
}

.token-progress {
  margin-top: 10px;
}

.token-explanation {
  margin: 15px 0;
  font-size: 14px;
  color: #606266;
}

.token-explanation p {
  margin: 8px 0;
}

.token-explanation ul {
  padding-left: 20px;
  margin: 8px 0;
}

.token-explanation li {
  margin-bottom: 4px;
}

.token-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 15px;
}

.token-reduce-progress {
  margin-top: 20px;
  padding: 10px;
  background-color: #f0f9eb;
  border-radius: 8px;
  font-size: 14px;
}

.input-connection-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background-color: #fff3e6;
  border-radius: 4px;
  font-size: 14px;
  color: #e6a23c;
  width: 100%;
  transition: all 0.3s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.input-connection-status .status-icon {
  animation: pulse 2s infinite;
  color: #e6a23c;
}

.input-connect-btn {
  margin-left: auto;
  transition: all 0.3s;
  background-color: #ecf5ff;
  border-color: #d9ecff;
  color: #409eff;
}

.input-connect-btn:hover {
  background-color: #409eff;
  border-color: #409eff;
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

.connection-notice {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background-color: #f9fafc;
  border-radius: 8px;
  margin-top: 20px;
}

.notice-icon {
  font-size: 40px;
  color: #e6a23c;
  animation: pulse 2s infinite;
  margin-bottom: 10px;
}

.notice-text {
  text-align: center;
  margin: 10px 0;
}

.notice-text h3 {
  font-size: 18px;
  color: #e6a23c;
  margin-bottom: 8px;
}

.notice-text p {
  font-size: 14px;
  color: #606266;
  margin: 0;
}

.notice-connect-btn {
  margin-top: 20px;
  background-color: #409eff;
  border-color: #409eff;
  color: #fff;
}

.notice-connect-btn:hover {
  background-color: #66b1ff;
  border-color: #66b1ff;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

.terminate-input-btn {
  background-color: #f56c6c;
  border-color: #f56c6c;
  color: #fff;
}

.terminate-input-btn:hover {
  background-color: #f78989;
  border-color: #f78989;
  box-shadow: 0 2px 8px rgba(245, 108, 108, 0.3);
}

.terminating {
  color: #f56c6c;
  background-color: #fef0f0;
  animation: pulse-terminate 1.5s infinite;
}

.terminating .thinking-icon {
  animation: rotate 1s linear infinite;
  color: #f56c6c;
}

@keyframes pulse-terminate {
  0% {
    background-color: #fef0f0;
  }
  50% {
    background-color: #fde2e2;
  }
  100% {
    background-color: #fef0f0;
  }
}

/* 响应时间对话框样式 */
.response-time-dialog-content {
  max-height: 60vh;
  overflow-y: auto;
  padding: 4px; /* 添加内边距 */
}

.response-time-info {
  margin-bottom: 16px;
  padding: 14px; /* 增加内边距 */
  background-color: #f0f9eb; /* 更改背景色 */
  border-radius: 8px; /* 增加圆角 */
  font-size: 14px;
  color: #67c23a; /* 更改文字颜色 */
  border-left: 3px solid #67c23a; /* 添加左边框 */
}

.response-time-summary {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
}

.summary-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.summary-label {
  font-weight: 500;
  color: #606266;
}

.summary-value {
  font-weight: 600;
  color: #303133;
}

.response-time-list {
  display: flex;
  flex-direction: column;
  gap: 14px; /* 增加间距 */
}

.response-time-item {
  padding: 14px; /* 增加内边距 */
  border-radius: 8px; /* 增加圆角 */
  background-color: #f9fafc; /* 更改背景色 */
  border-left: 3px solid #dcdfe6;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05); /* 添加阴影 */
}

.response-time-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 13px;
}

.response-number {
  font-weight: 600;
  color: #409eff;
}

.response-time {
  color: #909399;
}

.response-time-details {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.response-time-value {
  display: flex;
  align-items: center;
  gap: 4px;
}

.time-value {
  font-weight: 600;
}

.time-value.fast {
  color: #67c23a;
}

.time-value.medium {
  color: #e6a23c;
}

.time-value.slow {
  color: #f56c6c;
}

.terminated-tag {
  background-color: #f56c6c;
  border-color: #f56c6c;
  color: #fff;
  padding: 2px 4px;
  border-radius: 4px;
}

.response-preview {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.preview-label {
  font-weight: 500;
  color: #606266;
}

.preview-content {
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  color: #303133;
}

.user-preview {
  color: #409eff;
}

.ai-preview {
  color: #67c23a;
}

.response-time-indicator {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
  opacity: 0.7;
  transition: opacity 0.3s;
}

.time-badge {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #909399;
  background-color: #f4f4f5;
  padding: 2px 6px;
  border-radius: 10px;
}

/* 根据响应时间添加不同的颜色 */
.time-badge.fast {
  color: #67c23a;
  background-color: #f0f9eb;
}

.time-badge.medium {
  color: #e6a23c;
  background-color: #fdf6ec;
}

.time-badge.slow {
  color: #f56c6c;
  background-color: #fef0f0;
}

.message:hover .response-time-indicator {
  opacity: 1;
}
</style>
